from flask import Flask, request, session
from settings import *
from models import *
from flask_jwt_extended import create_access_token, jwt_required, JWTManager, get_jwt_identity
from flask_migrate import Migrate
from utils.md5 import *
import requests
from sqlalchemy.orm import aliased  # 用于同表连接，别名操作
from sqlalchemy import func  # 用于处理日期比较大小
import datetime
import random
import uuid
import smtplib
from email.mime.text import MIMEText

app = Flask(__name__)
app.config['JWT_SECRET_KEY'] = '123'
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = 720000
jwt = JWTManager(app)
app.config.from_object(MySQLConfig)
app.after_request(after_request)

migrate = Migrate(app, db)

with app.app_context():
    db.init_app(app)
    db.create_all()


# 用来对爬取的时间数据加上‘-’
def insert_dash(s, indices):
    sorted_indices = sorted(indices)
    new_s = s
    for i in range(len(sorted_indices)):
        new_s = new_s[:sorted_indices[i] + i] + '-' + new_s[sorted_indices[i] + i:]
    return new_s


@app.route('/api/send_code', methods=['POST'])
def send_code():
    data = json.loads(request.get_data())
    email = data['email']
    # 生成随机验证码
    code = str(random.randint(1000, 9999))
    # 发送邮件
    qq_mail = {
        'smtp_server': 'smtp.qq.com',
        'smtp_port': 25,
        'sender': '1665587834@qq.com',
        'password': 'rgfllubhxwaudaed',
    }
    # 构建邮件内容
    subject = '验证码'
    body = f'你的验证码是: {code}' \
           f'有效期是5分钟哦！'
    # 创建 MIMEText 对象
    msg = MIMEText(body, 'plain', 'utf-8')
    msg['Subject'] = subject
    msg['From'] = qq_mail['sender']
    msg['To'] = email
    # 发送邮件
    try:
        # 连接到 QQ 邮箱的 SMTP 服务器
        server = smtplib.SMTP(qq_mail['smtp_server'], qq_mail['smtp_port'])
        # 使用 SSL 加密连接
        # server = smtplib.SMTP_SSL(qq_mail['smtp_server'], qq_mail['smtp_port'])
        server.login(qq_mail['sender'], qq_mail['password'])
        server.sendmail(qq_mail['sender'], [email], msg.as_string())
        server.quit()
        return result(200, {"data": code})
    except Exception as e:
        print(e)
        return result(502, {"message": '出错了'})


@app.route('/api/sendMsg', methods=['POST'])
def send_msg():
    data = json.loads(request.get_data())
    email = data['email']
    text = data['text']
    # 生成随机验证码
    # 发送邮件
    qq_mail = {
        'smtp_server': 'smtp.qq.com',
        'smtp_port': 25,
        'sender': '1665587834@qq.com',
        'password': 'rgfllubhxwaudaed',
    }
    # 构建邮件内容
    subject = '重要通知:'
    body = f'{text}'

    # 创建 MIMEText 对象
    msg = MIMEText(body, 'plain', 'utf-8')
    msg['Subject'] = subject
    msg['From'] = qq_mail['sender']
    msg['To'] = email
    # 发送邮件
    try:
        # 连接到 QQ 邮箱的 SMTP 服务器
        server = smtplib.SMTP(qq_mail['smtp_server'], qq_mail['smtp_port'])
        # 使用 SSL 加密连接
        # server = smtplib.SMTP_SSL(qq_mail['smtp_server'], qq_mail['smtp_port'])
        server.login(qq_mail['sender'], qq_mail['password'])
        server.sendmail(qq_mail['sender'], [email], msg.as_string())
        server.quit()
        return result(200)
    except Exception as e:
        print(e)
        return result(502, {"message": '出错了'})


@app.route('/api/getEmail', methods=['POST'])
def get_email():
    data = json.loads(request.get_data())
    user_id = data['user_id']
    email = User.query.filter_by(id=user_id).first().email
    return result(200, {"email": email})


@app.route('/api/rePassword', methods=['POST'])
def reset_password():
    data = json.loads(request.get_data())
    username = data['username']
    password1 = data['password']
    password = md5(password1)
    User.query.filter_by(username=username).update({'password': password})
    db.session.commit()
    return result(200, {"data": password1})


@app.route("/api/resetEmail", methods=['POST'])
def reset_email():
    data = json.loads(request.get_data())
    username = data['username']
    email = data['email']
    User.query.filter_by(username=username).update({"email": email})
    db.session.commit()
    return result(200, {"data": email})


@app.route("/api/queryUser", methods=["GET", "POST"])
def query_user():
    if request.method == "GET":
        temps = User.query.all()
        data = dict()
        data["data"] = []
        for temp in temps:
            dic = temp.__dict__
            del dic["_sa_instance_state"]
            data["data"].append(dic)
        return result(200, data)
    else:
        data = json.loads(request.get_data())
        username = data['username']
        temps = User.query.filter_by(username=username)
        data = dict()
        data["data"] = []
        for temp in temps:
            dic = temp.__dict__
            del dic["_sa_instance_state"]
            data["data"].append(dic)
        return result(200, data)


@app.route("/api/login", methods=["POST"])
def login():
    data = json.loads(request.get_data())
    username = data["username"]
    password = data["password"]
    password = md5(password)

    temp = User.query.filter_by(username=username).first()
    if temp:
        if temp.password == password:
            access_token = create_access_token(identity=username)
            session["id"] = temp.id
            db.session.commit()
            return result(200, {"info": "登录成功", "token": access_token})
        else:
            return result(202, {"message": "密码不正确"})
    else:
        return result(201, {"message": "该用户不存在"})


@app.route("/api/info", methods=["GET"])
@jwt_required()
def info():
    current_user = get_jwt_identity()
    current_avatar = User.query.filter_by(username=current_user).first().avatar
    current_role = User.query.filter_by(username=current_user).first().role
    current_email = User.query.filter_by(username=current_user).first().email
    role = [current_role]
    return result(200, {"name": current_user, "avatar": current_avatar, "roles": role,"email": current_email})


@app.route("/api/editPower", methods=["POST"])
def edit_power():
    try:
        data = json.loads(request.get_data())
        user_id = data["user_id"]
        user_role = data["user_role"]
        User.query.filter_by(id=user_id).update({"role": user_role})
        db.session.commit()
        return result(200)
    except Exception as e:
        print(e)
        return result(502, {"message": "传入参数有误！"})


@jwt.expired_token_loader
def my_expired_token_callback(jwt_header, jwt_payload):
    return result(50008, {"message": "身份过期了"})


@app.route("/api/logout", methods=["POST"])
def logout():
    return result(200, {"message": "退出登录"})


@app.route("/api/register", methods=["POST"])
def register():
    if request.method == "POST":
        try:
            data = json.loads(request.get_data())
            username = data["username"]
            password = data["password"]
            password = md5(password)
            role = data["role"]
            email = data["email"]
            avatar = "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
            user = User(username=username, password=password, role=role, avatar=avatar, email=email)
            try:
                db.session.add(user)
                db.session.commit()
            except:
                return result(205, {"message": "用户已经存在！"})
            session["id"] = user.id
            return result(200)
        except:
            return result(502, {"message": "数据有误"})


@app.route("/api/addPassenger", methods=["POST"])
def add_passenger():
    if request.method == "POST":
        try:
            data = json.loads(request.get_data())
            name = data["name"]
            kind = data["kind"]
            card = data["card"]
            username = data["username"]
            user_id = User.query.filter_by(username=username).first().id
            temp = Passenger.query.filter_by(card=card).first()
            if temp:
                if temp.name != name:
                    return result(201, {"message": "乘车人姓名与身份证号不符"})
                elif temp.kind != kind:
                    return result(202, {"message": "乘车人类别不符"})
                elif temp.user_id == user_id:
                    return result(203, {"message": "该乘车人已经存在于该用户列表内！"})
            passenger = Passenger(name=name, kind=kind, card=card, user_id=user_id)
            print(passenger)
            try:
                db.session.add(passenger)
                db.session.commit()
            except:
                return result(205, {"message": "该乘车人信息不符！"})
            return result(200, {"data": user_id})
        except:
            return result(502, {"message": "数据有误"})


@app.route("/api/queryTypeByCard", methods=["POST"])
def query_type():
    data = json.loads(request.get_data())
    passenger_type = Passenger.query.filter_by(card=data["passenger_card"]).first().kind
    return result(200, {"kind": passenger_type})


@app.route("/api/queryPassenger", methods=["POST", "GET"])
def find_passenger():
    if request.method == "POST":
        try:
            data = json.loads(request.get_data())
            username = data["username"]
            user_id = User.query.filter_by(username=username).first().id
            temps = Passenger.query.filter_by(user_id=user_id).all()
            data = dict()
            data["data"] = []
            for temp in temps:
                dic = temp.__dict__
                del dic["_sa_instance_state"]
                data["data"].append(dic)
            return result(200, data)
        except:
            return result(502, {"message": "数据类型有误"})
    else:
        temps = Passenger.query.all()
        data = dict()
        data["data"] = []
        for temp in temps:
            dic = temp.__dict__
            del dic["_sa_instance_state"]
            data["data"].append(dic)
        return result(200, data)


@app.route("/api/editPassenger", methods=["POST"])
def edit_passenger():
    try:
        data = json.loads(request.get_data())
        name = data["name"]
        kind = data["kind"]
        card = data["card"]
        oldcard = data["oldcard"]
        user_id = data["user_id"]
        temps = Passenger.query.filter_by(card=card).all()
        victim = Passenger.query.filter_by(card=card, user_id=user_id).first()
        if victim and victim.name == name and victim.kind == kind:
            return result(201, {"message": "该用户的乘车人列表里已经存在身份证号为" + card + "的人"})
        else:
            if temps:
                for temp in temps:
                    temp.name = name
                    temp.kind = kind
                    db.session.commit()
                return result(200, {"message": "修改成功！"})
            else:
                old = Passenger.query.filter_by(card=oldcard, user_id=user_id).first()
                db.session.delete(old)
                db.session.commit()
                passenger = Passenger(name=name, kind=kind, card=card, user_id=user_id)
                db.session.add(passenger)
                db.session.commit()
                return result(200, {"message": "修改成功！"})
    except:
        return result(502, {"message": "数据有误"})


@app.route("/api/deletePassenger", methods=["GET", "POST"])
def delete_passenger():
    try:
        data = json.loads(request.get_data())
        user_id = data["user_id"]
        card = data["card"]
        temp = Passenger.query.filter_by(user_id=user_id, card=card).first()
        if temp:
            db.session.delete(temp)
            db.session.commit()
            return result(200, {"message": "删除成功"})
        else:
            return result(201, {"message": "所要删除的数据不存在"})
    except:
        return result(502, {"message": "数据有误"})


# 爬取12306数据
@app.route("/get_info")
def get_info():
    f = open('static/city.json', mode='r', encoding='utf-8')
    text = f.read()
    city_json = json.loads(text)
    start_date = datetime.date(2023, 9, 5)
    end_date = datetime.date(2023, 9, 7)
    random_date = start_date + datetime.timedelta(days=random.randint(0, (end_date - start_date).days))
    train_date = random_date.strftime("%Y-%m-%d")
    from_stations = ['BJP', 'VNP', 'BXP', 'IZQ', 'CUW', 'GGQ', 'SHH', 'SNH', 'AOH', 'SXH', 'TJP', 'TIP', 'TXP', 'CCT',
                     'CRT', 'ICW', 'CNW', 'CDW', 'CWQ', 'FZS', 'FYS', 'GIW', 'GZQ', 'HBB', 'VAB', 'HFH', 'NDC', 'HHC',
                     'HMQ', 'VUQ', 'HGH', 'HZH', 'JNK', 'JGK', 'LZJ', 'LAJ', 'NCG', 'NJH', 'NKH', 'NNZ', 'SJP', 'SYT',
                     'SBT', 'WHN', 'WMR', 'EAY', 'XNO', 'ZZF', 'AQH', 'BBH', 'BHZ', 'BIZ', 'BDC', 'BTC', 'BXT', 'CEH',
                     'IYH', 'CZH', 'DUT', 'DHL', 'DDW', 'DFT', 'DLT', 'RXW', 'ESN', 'FES', 'FJQ', 'FET', 'GBZ', 'GLZ',
                     'GBQ', 'GZG', 'GBT', 'HKN', 'HMR', 'EUH', 'HSN', 'HXZ', 'RNH', 'JBH', 'JJG', 'JLL', 'JAC', 'JUH',
                     'JFW', 'JZT', 'KFF', 'KNH', 'UAH', 'LCN', 'LYS', 'LLF', 'LZZ', 'LZD', 'MYW', 'NGH', 'NCW', 'PVD',
                     'PCW', 'QSW', 'QDK', 'QHX', 'QYS', 'QEH', 'RJG', 'SHD', 'NIW', 'SQF', 'SRG', 'SEQ', 'SYQ', 'SNN',
                     'SZQ', 'SZH', 'SZN', 'TGP', 'FUP', 'TSP', 'WCN', 'WKK', 'WHH', 'WXH', 'VRH', 'EFQ', 'XKS', 'XMS',
                     'XFN', 'XCH', 'YWY', 'HAN', 'TWQ', 'NUW', 'YAK', 'YWH', 'YON', 'YUQ', 'AOQ', 'ZBK', 'ZHQ', 'ZIQ',
                     'ZJH', 'ZEK', 'ADX', 'ARW', 'ARH', 'ALN', 'AXT', 'ASH', 'BWQ', 'BMH', 'BEP', 'BDP', 'BNN', 'BWH',
                     'IBQ', 'BLQ', 'BYT', 'CIN', 'CLK', 'DAQ', 'CPT', 'ESH', 'CXH', 'ICQ', 'CBP', 'DAG', 'UFQ', 'DXT',
                     'LFX', 'RHX', 'DRQ', 'DWT', 'RUH', 'DYW', 'DYH', 'EXH', 'IAW', 'EWH', 'DIP', 'ECN', 'FAS', 'FIH',
                     'FHH', 'FQS', 'FST', 'FDY', 'FBT', 'GCN', 'GGZ', 'GMK', 'GAG', 'GYF', 'GNQ', 'GSS', 'GAT', 'VXN',
                     'WKW', 'HCN', 'HXT', 'IGW', 'HJS', 'HPD', 'VQH', 'HDY', 'VCH', 'HEQ', 'HVQ', 'VZH', 'JJS', 'JWQ',
                     'JES', 'EGH', 'JRN', 'EAH', 'JNL', 'EPH', 'JZK', 'JBN', 'JZH', 'JOD', 'JOF', 'KSH', 'KXT', 'LPF',
                     'LJP', 'UFH', 'LKS', 'UJL', 'LIQ', 'USH', 'LSG', 'LAS', 'LET', 'UXP', 'LYK', 'LYT', 'LMH', 'LVS',
                     'LPQ', 'LQJ', 'MBN', 'MNF', 'MHQ', 'MQQ', 'MFQ', 'NES', 'NHH', 'NJS', 'NNQ', 'NOQ', 'NEH', 'PAW',
                     'PRT', 'PGZ', 'PBD', 'PTS', 'PWT', 'PWW', 'QAK', 'QYQ', 'QTP', 'QJN', 'INH', 'QXQ', 'QYH', 'QVH',
                     'QBQ', 'QDZ', 'QZK', 'RAH', 'RCG', 'RUQ', 'SBB', 'ORQ', 'OJQ', 'OLH', 'SNQ', 'SQH', 'IMH', 'SLC',
                     'SCF', 'OQH', 'PPT', 'SND', 'OHH', 'SRH', 'KAH', 'ITH', 'TMK', 'TID', 'PDQ', 'TKX', 'TJH', 'PXT',
                     'QSL', 'TNN', 'TLS', 'TVW', 'TSW', 'TCH', 'TRZ', 'TEK', 'TZH', 'WEQ', 'WFK', 'WXT', 'VHH', 'WBY',
                     'WNQ', 'WWP', 'WGH', 'IFH', 'EAQ', 'XPH', 'XRN', 'XAW', 'XOS', 'XIW', 'XSP', 'XDT', 'XAN', 'XWN',
                     'UUH', 'AIH', 'YGH', 'YDG', 'IIQ', 'EVH', 'URH', 'YGT', 'YXJ', 'YMN', 'YPP', 'UPH', 'ACG', 'YIG',
                     'YIQ', 'ZJJ', 'ZDP', 'ZDB', 'ZIN', 'ZDH', 'ZEH', 'ZOQ', 'ZTK', 'ZGQ', 'ZSQ', 'ZYN', 'ZUS', 'ZAQ',
                     'XPF', 'AXL', 'ADF', 'BMP', 'FEP', 'FHP', 'FCP', 'BBY', 'BRT', 'BFQ', 'FZW', 'BVT', 'UKZ', 'FWP',
                     'FHW', 'FOP', 'GUH', 'KNW', 'FVH', 'COW', 'CBQ', 'CNS', 'CBH', 'CNQ', 'CWT', 'DCZ', 'RDD', 'RWT',
                     'RGT', 'RMT', 'RTQ', 'DNY', 'DRH', 'OWH', 'DTO', 'DWG', 'DBN', 'KJW', 'DOP', 'FQW', 'IXW', 'EFN',
                     'FBZ', 'FDT', 'PUH', 'FUW', 'FEW', 'FZQ', 'NZQ', 'FDG', 'FZG', 'GCG', 'VUW', 'GMP', 'GCZ', 'FMW',
                     'GNN', 'KIW', 'GVW', 'GEZ', 'IMQ', 'FBQ', 'GQT', 'GAZ', 'GBS', 'GAJ', 'STS', 'KQW', 'GNP', 'HNS',
                     'HFF', 'HUL', 'HPP', 'KDQ', 'HDO', 'HTV', 'HTB', 'COH', 'ENH', 'KGN', 'KAN', 'HNN', 'KXN', 'KAQ',
                     'HCF', 'KHN', 'FAQ', 'KLQ', 'VLY', 'KMQ', 'IUQ', 'HPV', 'HOH', 'HVZ', 'HPN', 'KRN', 'KSN', 'NYH',
                     'HLN', 'KNN', 'HEK', 'HYT', 'HWV', 'KNQ', 'NSH', 'PFQ', 'JOL', 'JMP', 'JLS', 'JVK', 'JCS', 'JJH',
                     'OKH', 'JUS', 'JNJ', 'JWH', 'NRH', 'JDV', 'LOH', 'JXG', 'JOW', 'JBJ', 'PYH', 'JZV', 'QKW', 'KTQ',
                     'KVW', 'IDZ', 'UCZ', 'LCF', 'NWW', 'ACQ', 'FVW', 'LVO', 'UOQ', 'UQQ', 'INW', 'LLQ', 'LXV', 'KGQ',
                     'UDP', 'LBN', 'IKW', 'KFW', 'UKQ', 'UDV', 'IVW', 'LDH', 'KRW', 'LBK', 'LEH', 'LNR', 'LSZ', 'LDJ',
                     'OMH', 'MDN', 'MBJ', 'MBK', 'MBS', 'IUW', 'MSN', 'MYO', 'MZF', 'NEF', 'NDG']  # 出发地简称缩写列表
    to_stations = ['NDG', 'NEF', 'MZF', 'MYO', 'MSN', 'IUW', 'MBS', 'MBK', 'MBJ', 'MDN', 'OMH', 'LDJ', 'LSZ', 'LNR',
                   'LEH', 'LBK', 'LDH', 'KRW', 'IVW', 'UDV', 'UKQ', 'KFW', 'IKW', 'LLQ', 'INW', 'UQQ', 'UOQ', 'LVO',
                   'FVW', 'ACQ', 'NWW', 'LCF', 'UCZ', 'IDZ', 'KVW', 'KTQ', 'QKW', 'JZV', 'PYH', 'JBJ', 'JOW', 'JXG',
                   'LOH', 'JDV', 'NRH', 'JWH', 'JNJ', 'JUS', 'OKH', 'JJH', 'JCS', 'JVK', 'JLS', 'JMP', 'JOL', 'PFQ',
                   'NSH', 'KNQ', 'HWV', 'HYT', 'HEK', 'HLN', 'NYH', 'KXN', 'HNN', 'KAN', 'KGN', 'ENH', 'COH', 'HTB',
                   'HTV', 'HDO', 'KDQ', 'HPP', 'HUL', 'HFF', 'HNS', 'GNP', 'STS', 'GAJ', 'GBS', 'GAZ', 'GQT', 'FBQ',
                   'IMQ', 'GEZ', 'GVW', 'KIW', 'GNN', 'FMW', 'GCZ', 'GMP', 'VUW', 'GCG', 'FZG', 'FDG', 'NZQ', 'FZQ',
                   'FEW', 'FUW', 'PUH', 'FDT', 'FBZ', 'EFN', 'IXW', 'FQW', 'DOP', 'KJW', 'DBN', 'DWG', 'DTO', 'OWH',
                   'DRH', 'DNY', 'RTQ', 'RMT', 'RGT', 'RWT', 'RDD', 'DCZ', 'CWT', 'CNQ', 'CBH', 'CNS', 'CBQ', 'COW',
                   'FVH', 'KNW', 'GUH', 'FOP', 'FHW', 'FWP', 'UKZ', 'BVT', 'FZW', 'BFQ', 'BRT', 'BBY', 'FCP', 'FHP',
                   'FEP', 'BMP', 'ADF', 'AXL', 'XPF', 'ZAQ', 'ZUS', 'ZYN', 'ZSQ', 'ZGQ', 'ZTK', 'ZOQ', 'ZEH', 'ZDH',
                   'ZIN', 'ZDB', 'ZDP', 'ZJJ', 'YIQ', 'YIG', 'ACG', 'UPH', 'YPP', 'YMN', 'YXJ', 'YGT', 'URH', 'EVH',
                   'IIQ', 'YDG', 'YGH', 'AIH', 'UUH', 'XWN', 'XAN', 'XDT', 'XSP', 'XIW', 'XOS', 'XAW', 'XRN', 'XPH',
                   'EAQ', 'IFH', 'WGH', 'WWP', 'WNQ', 'WBY', 'VHH', 'WXT', 'WFK', 'WEQ', 'TZH', 'TEK', 'TRZ', 'TCH',
                   'TSW', 'TVW', 'TLS', 'TNN', 'QSL', 'PXT', 'TJH', 'TKX', 'PDQ', 'TID', 'TMK', 'ITH', 'KAH', 'SRH',
                   'OHH', 'SND', 'PPT', 'OQH', 'SCF', 'SLC', 'IMH', 'SQH', 'SNQ', 'OLH', 'OJQ', 'ORQ', 'SBB', 'RUQ',
                   'RCG', 'RAH', 'QZK', 'QDZ', 'QBQ', 'QVH', 'QYH', 'QXQ', 'INH', 'QJN', 'QTP', 'QYQ', 'QAK', 'PWW',
                   'PWT', 'PTS', 'PBD', 'PGZ', 'PRT', 'PAW', 'NEH', 'NOQ', 'NNQ', 'NJS', 'NHH', 'NES', 'MFQ', 'MQQ',
                   'MHQ', 'MNF', 'MBN', 'LQJ', 'LPQ', 'LVS', 'LMH', 'LYT', 'LYK', 'UXP', 'LET', 'LAS', 'LSG', 'USH',
                   'LIQ', 'UJL', 'LKS', 'UFH', 'LJP', 'LPF', 'KXT', 'KSH', 'JOF', 'JOD', 'JZH', 'JBN', 'JZK', 'EPH',
                   'JNL', 'EAH', 'JRN', 'EGH', 'JES', 'JWQ', 'JJS', 'VZH', 'HEQ', 'VCH', 'HDY', 'VQH', 'HPD', 'HJS',
                   'IGW', 'HXT', 'HCN', 'WKW', 'VXN', 'GAT', 'GSS', 'GNQ', 'GYF', 'GAG', 'GMK', 'GGZ', 'GCN', 'FBT',
                   'FDY', 'FST', 'FQS', 'FHH', 'FIH', 'FAS', 'ECN', 'DIP', 'EWH', 'IAW', 'EXH', 'DYH', 'DYW', 'RUH',
                   'DWT', 'DRQ', 'RHX', 'LFX', 'DXT', 'UFQ', 'DAG', 'CBP', 'ICQ', 'CXH', 'ESH', 'CPT', 'DAQ', 'CLK',
                   'CIN', 'BYT', 'BLQ', 'IBQ', 'BWH', 'BNN', 'BDP', 'BEP', 'BMH', 'BWQ', 'ASH', 'AXT', 'ALN', 'ARH',
                   'ARW', 'ADX', 'ZEK', 'ZJH', 'ZIQ', 'ZHQ', 'ZBK', 'AOQ', 'YUQ', 'YON', 'YWH', 'YAK', 'NUW', 'TWQ',
                   'HAN', 'YWY', 'XCH', 'XFN', 'XMS', 'XKS', 'EFQ', 'VRH', 'WXH', 'WHH', 'WKK', 'WCN', 'TSP', 'FUP',
                   'TGP', 'SZN', 'SZH', 'SZQ', 'SNN', 'SYQ', 'SEQ', 'SRG', 'SQF', 'NIW', 'SHD', 'RJG', 'QEH', 'QYS',
                   'QHX', 'QDK', 'QSW', 'PCW', 'PVD', 'NCW', 'NGH', 'MYW', 'LZD', 'LZZ', 'LLF', 'LYS', 'LCN', 'UAH',
                   'KNH', 'KFF', 'JZT', 'JFW', 'JUH', 'JAC', 'JLL', 'JJG', 'JBH', 'RNH', 'HXZ', 'HSN', 'EUH', 'HMR',
                   'HKN', 'GBT', 'GZG', 'GBQ', 'GLZ', 'GBZ', 'FET', 'FJQ', 'FES', 'ESN', 'RXW', 'DLT', 'DFT', 'DDW',
                   'DHL', 'DUT', 'CZH', 'IYH', 'CEH', 'BXT', 'BTC', 'BDC', 'BIZ', 'BHZ', 'BBH', 'AQH', 'ZZF', 'XNO',
                   'EAY', 'WMR', 'WHN', 'SBT', 'SYT', 'SJP', 'NNZ', 'NKH', 'NJH', 'NCG', 'LAJ', 'LZJ', 'JGK', 'JNK',
                   'HZH', 'HGH', 'VUQ', 'HMQ', 'HHC', 'NDC', 'HFH', 'VAB', 'HBB', 'GZQ', 'GIW', 'FYS', 'FZS', 'CWQ',
                   'CDW', 'CNW', 'ICW', 'CRT', 'CCT', 'TXP', 'TIP', 'TJP', 'SXH', 'AOH', 'SNH', 'SHH', 'GGQ', 'CUW',
                   'IZQ', 'BXP', 'VNP', 'BJP']  # 目的地简称缩写列表
    for from_station, to_station in zip(from_stations, to_stations):
        url = f"https://kyfw.12306.cn/otn/leftTicketPrice/query?leftTicketDTO.train_date={train_date}&leftTicketDTO.from_station={from_station}&leftTicketDTO.to_station={to_station}&leftTicketDTO.ticket_type=1&randCode=stzh"
        res = requests.get(url)
        data = res.json()
        queryLeftNewDTO_list = [item['queryLeftNewDTO'] for item in data['data']]
        if queryLeftNewDTO_list:
            for item in queryLeftNewDTO_list:
                train_no = item["train_no"]
                train_number = item["station_train_code"]
                start_station = item["start_station_name"]
                end_station = item["end_station_name"]
                try:
                    useless1 = city_json[start_station]
                    useless2 = city_json[end_station]
                    indices = [4, 6]
                    arrive_day = insert_dash(item["start_train_date"], indices)
                    victim = Train.query.filter_by(train_no=train_no, arrive_day=arrive_day).first()
                    if victim:
                        pass
                    else:
                        if "G" in train_number:
                            train_carriage = 8
                        elif "D" in train_number:
                            train_carriage = 6
                        else:
                            train_carriage = 4
                        temp = Train(train_no=train_no, train_number=train_number, start_station=start_station,
                                     end_station=end_station,
                                     arrive_day=arrive_day, train_carriage=train_carriage)
                        db.session.add(temp)
                        db.session.commit()
                except:
                    pass
                # start_time = item["start_time"]
                # arrive_time = item["arrive_time"]
    return result(200)


# 尝试爬取12306的经停站信息
@app.route("/get_station")
def get_station():
    f = open('static/city.json', mode='r', encoding='utf-8')
    text = f.read()
    city_json = json.loads(text)
    temps = Train.query.all()
    for item in temps:
        train_no = item.train_no
        train_number = item.train_number
        arrive_day = item.arrive_day
        start_station_code = city_json[item.start_station]
        end_station_code = city_json[item.end_station]
        url = f"https://kyfw.12306.cn/otn/czxx/queryByTrainNo?train_no={train_no}&from_station_telecode={start_station_code}&to_station_telecode={end_station_code}&depart_date={arrive_day}"
        res = requests.get(url)
        data = res.json()
        data = data["data"]
        data = data["data"]
        for mes in data:
            station_no = mes["station_no"]
            station_name = mes["station_name"]
            arrive_time = mes["arrive_time"]
            start_time = mes["start_time"]
            parking = Parking(train_no=train_no, train_number=train_number, arrive_day=arrive_day,
                              station_no=station_no, station_name=station_name, arrive_time=arrive_time,
                              start_time=start_time
                              )
            db.session.add(parking)
            db.session.commit()
    return result(200, {"message": "初始化成功！"})


@app.route("/init_se_time")
def init_se_time():
    temps = Train.query.all()
    for item in temps:
        train_no = item.train_no
        arrive_day = item.arrive_day
        start_station = item.start_station
        end_station = item.end_station
        parking1 = Parking.query.filter_by(train_no=train_no, arrive_day=arrive_day, station_name=start_station).first()
        parking2 = Parking.query.filter_by(train_no=train_no, arrive_day=arrive_day, station_name=end_station).first()
        Train.query.filter_by(train_no=train_no, arrive_day=arrive_day).update({"start_time": parking1.start_time,
                                                                                "end_time": parking2.arrive_time})
        db.session.commit()
    return result(200, {"message": "success"})


# 初始化坐席信息
@app.route("/init_seat")
def init_seat():
    try:
        temps = Train.query.all()
        for temp in temps:
            train_no = temp.train_no
            arrive_day = temp.arrive_day
            count = temp.train_carriage
            c = 1
            while c <= count:
                if c == 1 or c == 2:
                    victim = Seat(train_no=train_no, arrive_day=arrive_day, carriage_no=c, seat_type="商务座",
                                  seat_count=20)
                    db.session.add(victim)
                    db.session.commit()
                    c = c + 1
                elif c == 3 or c == 4:
                    victim = Seat(train_no=train_no, arrive_day=arrive_day, carriage_no=c, seat_type="一等座",
                                  seat_count=30)
                    db.session.add(victim)
                    db.session.commit()
                    c = c + 1
                else:
                    victim = Seat(train_no=train_no, arrive_day=arrive_day, carriage_no=c, seat_type="二等座",
                                  seat_count=50)
                    db.session.add(victim)
                    db.session.commit()
                    c = c + 1
        return result(200)
    except:
        return result(502, {"message": "初始化数据时出错了"})


@app.route("/api/queryTrain", methods=["GET", "POST"])
def find_train():
    if request.method == "GET":
        temps = Train.query.all()
        data = dict()
        data["data"] = []
        for temp in temps:
            dic = temp.__dict__
            del dic["_sa_instance_state"]
            data["data"].append(dic)
        return result(200, data)
    elif request.method == "POST":
        try:
            data = json.loads(request.get_data())
            train_number = data["train_number"]
            str1 = "%" + train_number + "%"
            temps = Train.query.filter(Train.train_number.like(str1)).all()
            data = dict()
            data["data"] = []
            for temp in temps:
                dic = temp.__dict__
                del dic["_sa_instance_state"]
                data["data"].append(dic)
            return result(200, data)
        except:
            return result(502, {"message": "数据有误"})


@app.route("/api/user/queryTrain", methods=["GET", "POST"])
def user_find_train():
    try:
        data = json.loads(request.get_data())
        arrive_day = data["arrive_day"]
        start_station = data["start_station"]
        end_station = data["end_station"]
        str1 = "%" + start_station + "%"
        str2 = "%" + end_station + "%"
        p1 = aliased(Parking)
        p2 = aliased(Parking)

        connection = db.session.query(p1.train_no, p1.train_number, p1.station_name,
                                      p2.station_name, p1.start_time, p2.arrive_time, p1.arrive_day,
                                      p1.station_no, p2.station_no) \
            .filter(p1.arrive_day == arrive_day, p1.station_name.like(str1), p2.station_name.like(str2),
                    p2.arrive_day == arrive_day, p1.train_no == p2.train_no, p1.station_no < p2.station_no)

        data = dict()
        data["data"] = []
        for temp in connection:
            data["data"].append({"train_no": temp[0], "train_number": temp[1], "start_station": temp[2],
                                 "end_station": temp[3], "start_time": temp[4], "end_time": temp[5],
                                 "arrive_day": temp[6], "start_station_no": temp[7], "end_station_no": temp[8]})
        return result(200, data)
    except:
        return result(502, {"message": "数据有误"})


@app.route("/api/user/transfer", methods=["POST"])
def user_transfer():
    try:
        data = json.loads(request.get_data())
        arrive_day = data["arrive_day"]
        start_station = data["start_station"]
        end_station = data["end_station"]
        str1 = "%" + start_station + "%"
        str2 = "%" + end_station + "%"
        p1 = aliased(Parking)
        p2 = aliased(Parking)
        p3 = aliased(Parking)
        p4 = aliased(Parking)

        connections = db.session.query(p1.train_number, p1.start_time, p1.station_name, p2.station_name, p2.arrive_time,
                                       p3.start_time, p4.train_number, p4.station_name, p4.arrive_time, p1.arrive_day,
                                       p1.station_no, p2.station_no, p4.station_no, p1.train_no, p4.train_no,
                                       p3.station_no) \
            .filter(p1.station_name.like(str1), p4.station_name.like(str2),
                    p2.station_name == p3.station_name, p1.train_no == p2.train_no,
                    p3.train_no == p4.train_no, p1.train_no != p3.train_no,
                    func.time_format(p2.arrive_time, "%H:%i") < func.time_format(p3.arrive_time, "%H:%i"),
                    p1.station_no < p2.station_no, p3.station_no < p4.station_no,
                    p1.arrive_day == arrive_day, p3.arrive_day == arrive_day,
                    p2.arrive_day == arrive_day, p4.arrive_day == arrive_day)
        data = []
        for temp in connections:
            data.append(
                {"t1_number": temp[0], "t1_start_time": temp[1], "t1_start_station": temp[2], "t1_end_time": temp[4]
                    , "t1_end_station": temp[3], "t2_number": temp[6], "t2_start_time": temp[5],
                 "t2_start_station": temp[3], "t2_end_time": temp[8]
                    , "t2_end_station": temp[7], "arrive_day": temp[9],
                 "start_station_no": temp[10], "middle_station_no": temp[11], "end_station_no": temp[12],
                 "t1_no": temp[13], "t2_no": temp[14], "middle2_station_no": temp[15]
                 })
        return result(200, data)
    except:
        return result(502, {"message": "error"})


@app.route("/api/addTrain", methods=["POST"])
def add_train():
    try:
        data = json.loads(request.get_data())
        train_no = data["train_no"]
        train_number = data["train_number"]
        train_carriage = data["train_carriage"]
        start_station = data["start_station"]
        end_station = data["end_station"]
        start_time = data["start_time"]
        end_time = data["end_time"]
        arrive_day = data["arrive_day"]
        temp = Train.query.filter_by(train_no=train_no, train_number=train_number, arrive_day=arrive_day).first()
        if temp:
            return result(201, {"message": "该车次已经存在了"})
        else:
            train = Train(train_no=train_no, train_number=train_number, train_carriage=train_carriage,
                          start_station=start_station, end_station=end_station, start_time=start_time,
                          end_time=end_time, arrive_day=arrive_day)
            db.session.add(train)
            db.session.commit()
            return result(200, {"message": "添加成功"})
    except:
        return result(502, {"message": "数据有误"})


@app.route("/api/deleteTrain", methods=["POST"])
def delete_train():
    try:
        data = json.loads(request.get_data())
        train_no = data["train_no"]
        train_number = data["train_number"]
        arrive_day = data["arrive_day"]
        temp = Train.query.filter_by(train_no=train_no, train_number=train_number, arrive_day=arrive_day).first()
        if temp:
            db.session.delete(temp)
            db.session.commit()
            return result(200, {"message": "删除成功"})
        else:
            return result(202, {"message": "不存在该车次信息"})
    except:
        return result(502, {"message": "数据有误"})


@app.route("/api/editTrain", methods=["POST"])
def edit_train():
    try:
        data = json.loads(request.get_data())
        train_no = data["train_no"]
        train_number = data["train_number"]
        # train_carriage = data["train_carriage"]
        start_station = data["start_station"]
        end_station = data["end_station"]
        start_time = data["start_time"]
        end_time = data["end_time"]
        arrive_day = data["arrive_day"]
        Train.query.filter_by(train_no=train_no, train_number=train_number, arrive_day=arrive_day).update(
            {"start_time": start_time, "end_time": end_time, "start_station": start_station,
             "end_station": end_station})
        db.session.commit()
        return result(200, {"message": "修改成功！"})
    except:
        return result(502, {"message": "数据有误"})


@app.route("/api/querySeat", methods=["POST", "GET"])
def find_seat():
    if request.method == "GET":
        temps = Seat.query.all()
        data = dict()
        data["data"] = []
        for temp in temps:
            dic = temp.__dict__
            del dic["_sa_instance_state"]
            data["data"].append(dic)
        return result(200, data)
    elif request.method == "POST":
        try:
            data = json.loads(request.get_data())
            arrive_day = data["arrive_day"]
            start_station_no = data["start_station_no"]
            end_station_no = data["end_station_no"]
            try:
                train_no = data["train_no"]
                temps = Seat.query.filter_by(train_no=train_no, arrive_day=arrive_day).all()
                query1 = db.session.query(Orders.train_no, Orders.carriage_no, Orders.seat_no) \
                    .filter(Orders.start_station_no < start_station_no,
                            Orders.end_station_no > end_station_no,
                            Orders.train_no == train_no, Orders.arrive_day == arrive_day,
                            Orders.status != '已退票', Orders.status != '已改签',
                            Orders.status != '已超时')
                query2 = db.session.query(Orders.train_no, Orders.carriage_no, Orders.seat_no) \
                    .filter(Orders.start_station_no < end_station_no,
                            Orders.end_station_no > end_station_no,
                            Orders.train_no == train_no, Orders.arrive_day == arrive_day,
                            Orders.status != '已退票', Orders.status != '已改签',
                            Orders.status != '已超时')
                query3 = db.session.query(Orders.train_no, Orders.carriage_no, Orders.seat_no) \
                    .filter(Orders.start_station_no >= start_station_no,
                            Orders.end_station_no <= end_station_no,
                            Orders.train_no == train_no, Orders.arrive_day == arrive_day,
                            Orders.status != '已退票', Orders.status != '已改签',
                            Orders.status != '已超时')
                query4 = db.session.query(Orders.train_no, Orders.carriage_no, Orders.seat_no) \
                    .filter(Orders.start_station_no < start_station_no,
                            Orders.end_station_no > start_station_no,
                            Orders.train_no == train_no, Orders.arrive_day == arrive_day,
                            Orders.status != '已退票', Orders.status != '已改签',
                            Orders.status != '已超时')
                union_query = query1.union(query2).union(query3).union(query4).all()
            except:
                train_number = data["train_number"]
                train_no = Train.query.filter_by(train_number=train_number, arrive_day=arrive_day).first().train_no
                temps = Seat.query.filter_by(train_no=train_no, arrive_day=arrive_day).all()
                query1 = db.session.query(Orders.train_no, Orders.carriage_no, Orders.seat_no) \
                    .filter(Orders.start_station_no < start_station_no,
                            Orders.end_station_no > end_station_no,
                            Orders.train_no == train_no, Orders.arrive_day == arrive_day,
                            Orders.status != '已退票', Orders.status != '已改签',
                            Orders.status != '已超时')
                query2 = db.session.query(Orders.train_no, Orders.carriage_no, Orders.seat_no) \
                    .filter(Orders.start_station_no < end_station_no,
                            Orders.end_station_no > end_station_no,
                            Orders.train_no == train_no, Orders.arrive_day == arrive_day,
                            Orders.status != '已退票', Orders.status != '已改签',
                            Orders.status != '已超时')
                query3 = db.session.query(Orders.train_no, Orders.carriage_no, Orders.seat_no) \
                    .filter(Orders.start_station_no >= start_station_no,
                            Orders.end_station_no <= end_station_no,
                            Orders.train_no == train_no, Orders.arrive_day == arrive_day,
                            Orders.status != '已退票', Orders.status != '已改签',
                            Orders.status != '已超时')
                query4 = db.session.query(Orders.train_no, Orders.carriage_no, Orders.seat_no) \
                    .filter(Orders.start_station_no < start_station_no,
                            Orders.end_station_no > start_station_no,
                            Orders.train_no == train_no, Orders.arrive_day == arrive_day,
                            Orders.status != '已退票', Orders.status != '已改签',
                            Orders.status != '已超时')
                union_query = query1.union(query2).union(query3).union(query4).all()
            data = dict()
            data["data"] = []
            data["cook"] = []
            # temps为一个列表
            for temp in temps:
                dic = temp.__dict__
                del dic["_sa_instance_state"]
                data["data"].append(dic)
            # union_query为一个列表，列表中元素为元组
            for temp in union_query:
                data["cook"].append({"train_no": temp[0], "carriage_no": temp[1], "seat_no": temp[2]})
            return result(200, data)
        except:
            return result(502, {"message": "数据有误"})


@app.route("/api/user/querySeatInfo", methods=["POST", "GET"])
def query_seat_info():
    if request.method == 'GET':
        temps = Seat.query.all()
        data = dict()
        data["data"] = []
        for temp in temps:
            dic = temp.__dict__
            del dic["_sa_instance_state"]
            data["data"].append(dic)
        return result(200, data)
    else:
        data = json.loads(request.get_data())
        train_number = data['train_number']
        arrive_day = data['arrive_day']
        train = Train.query.filter_by(arrive_day=arrive_day, train_number=train_number).first()
        if train:
            train_no = train.train_no
            temps = Seat.query.filter_by(train_no=train_no, arrive_day=arrive_day)
            data = dict()
            data["data"] = []
            for temp in temps:
                dic = temp.__dict__
                del dic["_sa_instance_state"]
                data["data"].append(dic)
            return result(200, data)
        else:
            return result(202, {"message": "没有该信息哦！"})


@app.route("/api/deleteSeat", methods=["POST"])
def delete_seat():
    try:
        data = json.loads(request.get_data())
        train_no = data["train_no"]
        carriage_no = data["carriage_no"]
        arrive_day = data["arrive_day"]
        print(arrive_day, train_no, carriage_no)
        temp = Seat.query.filter_by(train_no=train_no, carriage_no=carriage_no, arrive_day=arrive_day).first()
        print()
        if temp:
            db.session.delete(temp)
            db.session.commit()
            return result(200, {"message": "删除成功"})
        else:
            return result(201, {"message": "数据不存在"})
    except:
        return result(502, {"message": "数据错误"})


@app.route("/api/addSeat", methods=["POST"])
def add_seat():
    try:
        data = json.loads(request.get_data())
        train_no = data['train_no']
        carriage_no = data['carriage_no']
        seat_type = data['seat_type']
        arrive_day = data['arrive_day']
        seat_count = int(data['seat_count'])
        temp = Train.query.filter_by(train_no=train_no, arrive_day=arrive_day)
        if temp:
            c1 = int(carriage_no)
            c2 = int(temp[0].train_carriage)
            if c1 > c2:
                return result(203, {"message": "该车次不存在该车厢"})
            else:
                seat = Seat(train_no=train_no, carriage_no=carriage_no, seat_count=seat_count, seat_type=seat_type,
                            arrive_day=arrive_day)
                db.session.add(seat)
                db.session.commit()
                return result(200)
        else:
            return result(202, {"message": "该车次不存在"})
    except Exception as e:
        print(e)
        return result(502, {"message": "数据有误"})


@app.route("/api/editSeat", methods=["POST"])
def edit_seat():
    try:
        data = json.loads(request.get_data())
        train_no = data['train_no']
        carriage_no = data['carriage_no']
        seat_type = data['seat_type']
        arrive_day = data['arrive_day']
        seat_count = int(data['seat_count'])
        print("---------")
        temp = Train.query.filter_by(train_no=train_no, arrive_day=arrive_day)
        if temp:
            c1 = int(carriage_no)
            c2 = int(temp[0].train_carriage)
            if c1 > c2:
                return result(203, {"message": "该车次不存在该车厢"})
            else:
                seat = Seat.query.filter_by(arrive_day=arrive_day, train_no=train_no).update({"seat_type": seat_type,
                                                                                             "seat_count": seat_count,
                                                                                              "carriage_no": carriage_no})
                db.session.commit()
                return result(200)
        else:
            return result(202, {"message": "该车次不存在"})
    except Exception as e:
        print(e)
        return result(502, {"message": "数据有误"})


# 下面是经停站信息查询
@app.route("/api/user/queryParking", methods=["POST"])
def find_parking():
    try:
        data = json.loads(request.get_data())
        arrive_day = data["arrive_day"]
        try:
            train_no = data["train_no"]
            temps = Parking.query.filter_by(train_no=train_no, arrive_day=arrive_day).all()
        except:
            train_number = data["train_number"]
            train_no = Train.query.filter_by(train_number=train_number, arrive_day=arrive_day).first().train_no
            temps = Parking.query.filter_by(train_no=train_no, arrive_day=arrive_day).all()
        data = dict()
        data["data"] = []
        for temp in temps:
            dic = temp.__dict__
            del dic["_sa_instance_state"]
            data["data"].append(dic)
        return result(200, data)
    except:
        return result(502, {"message": "数据有误"})


# 下面是订单相关信息
@app.route("/api/user/initOrder", methods=["POST"])
def init_order():
    try:
        data = json.loads(request.get_data())
        user_id = User.query.filter_by(username=data["username"]).first().id
        passenger_card = data["passenger_card"]
        train_no = data["train_no"]
        arrive_day = data["arrive_day"]
        start_station_name = data["start_station_name"]
        start_station_no = data["start_station_no"]
        end_station_name = data["end_station_name"]
        end_station_no = data["end_station_no"]
        carriage_no = data["carriage_no"]
        print("-------")
        seat_no = data["seat_no"]
        price = data["price"]
        create_time = data["create_time"]
        passenger_name = Passenger.query.filter_by(card=passenger_card).first().name
        # 查询一下该车厢的座位数目
        # 通过uuid生成订单的id
        order_id = str(uuid.uuid4().hex)
        victim = Seat.query.filter_by(train_no=train_no, arrive_day=arrive_day, carriage_no=carriage_no).first()
        flag = plus_counter(train_no, carriage_no, arrive_day, victim.seat_count, user_id, passenger_card, order_id)
        print('flag:', flag)
        if flag:
            if flag == -1:
                return result(204, {"message": "已经为该乘客购买了本车次车票"})
            elif flag == -2:
                return result(205, {"message": "已经为该乘客抢到了车票，但是还未付款"})
            else:
                try:
                    # 把订单信息放入redis中，并设置过期时间
                    order_info = {
                        "order_id": order_id,
                        "user_id": user_id,
                        "passenger_card": passenger_card,
                        "train_no": train_no,
                        "carriage_no": carriage_no,
                        "arrive_day": arrive_day,
                        "start_station_name": start_station_name,
                        "start_station_no": start_station_no,
                        "end_station_name": end_station_name,
                        "end_station_no": end_station_no,
                        "seat_no": seat_no,
                        "price": price,
                        "create_time": create_time,
                    }
                    create_order(order_info)
                    # 设置订单队列
                    print("进入订单队列")
                    create_order_queue(order_info)
                    # 设置死信队列
                    create_dead_queue(order_info)
                    print("成功")
                    request.close()
                    return result(200, {"message": "购票成功，请在15分钟内付款！",
                                        "data": {"train_no": train_no, "arrive_day": arrive_day,
                                                 "carriage_no": carriage_no, "passenger_name": passenger_name,
                                                 "order_id": order_id, "user_id": user_id, "price": price,
                                                 "seat_no": seat_no,
                                                 "start_station_no": start_station_no,
                                                 "end_station_name": end_station_name,
                                                 "end_station_no": end_station_no,
                                                 "start_station_name": start_station_name,
                                                 "create_time": create_time,
                                                 "passenger_card": passenger_card}})
                except Exception as e:
                    print(e)
                    return result(400, {"message": "由于网络异常，购票失败，请检查网络！"})
        else:
            return result(201, {"message": "购票失败，该车厢座位已售罄！"})
    except:
        return result(502, {"message": "数据有误"})


@app.route("/api/user/pay", methods=["POST", "GET"])
def user_pay():
    data = json.loads(request.get_data())
    order_info = data
    order_status = check_order(order_info)
    if order_status:
        if order_status == -1:
            return result(202, {"message": "订单已超时"})
        else:
            # 此处应该有一个支付函数逻辑，比如支付宝沙箱
            out_trade_no = order_info['order_id']
            price = order_info['price']
            total_amount = int(price[1:])
            order_string = alipay.api_alipay_trade_page_pay(
                out_trade_no=out_trade_no,
                total_amount=total_amount,
                subject='火车票支付',
                return_url='http://localhost:9528/#/success')
            url = "https://openapi-sandbox.dl.alipaydev.com/gateway.do?" + order_string
            return result(200, {"url": url})
    else:
        return result(203, {"message": "参数有误,数据不一致"})


@app.route("/alipay", methods=["POST", "GET"])
def user_paid():
    data = json.loads(request.get_data())
    order_id = data['order_id']
    temp = Orders.query.filter_by(id=order_id).first()
    order_info = {
        "order_id": order_id,
        "user_id": temp.user_id,
        "passenger_card": temp.passenger_card,
        "train_no": temp.train_no,
        "carriage_no": temp.carriage_no,
        "arrive_day": temp.arrive_day,
        "start_station_name": temp.start_station_name,
        "start_station_no": temp.start_station_no,
        "end_station_name": temp.end_station_name,
        "end_station_no": temp.end_station_no,
        "seat_no": temp.seat_no,
        "price": temp.price,
        "create_time": temp.create_time.strftime('%Y-%m-%d %H:%M:%S'),
    }
    create_paid_queue(order_info)
    return result(200)


@app.route("/api/user/rebook_first", methods=["POST"])
def user_rebook_first():
    try:
        data = json.loads(request.get_data())
        user_id = User.query.filter_by(username=data["username"]).first().id
        passenger_card = data["passenger_card"]
        train_no = data["train_no"]
        arrive_day = data["arrive_day"]
        start_station_name = data["start_station_name"]
        start_station_no = data["start_station_no"]
        end_station_name = data["end_station_name"]
        end_station_no = data["end_station_no"]
        carriage_no = data["carriage_no"]
        seat_no = data["seat_no"]
        price = data["price"]
        create_time = data["create_time"]
        passenger_name = Passenger.query.filter_by(card=passenger_card).first().name
        order_id = str(uuid.uuid4().hex)
        victim = Seat.query.filter_by(train_no=train_no, arrive_day=arrive_day, carriage_no=carriage_no).first()
        flag = plus_counter(train_no, carriage_no, arrive_day, victim.seat_count, user_id, passenger_card, order_id)
        print('flag:', flag)
        if flag:
            if flag == -1:
                return result(204, {"message": "已经为该乘客购买了本车次车票"})
            elif flag == -2:
                return result(205, {"message": "已经为该乘客抢到了车票，但是还未付款"})
            else:
                try:
                    # 把订单信息放入redis中，并设置过期时间
                    order_info = {
                        "order_id": order_id,
                        "user_id": user_id,
                        "passenger_card": passenger_card,
                        "train_no": train_no,
                        "carriage_no": carriage_no,
                        "arrive_day": arrive_day,
                        "start_station_name": start_station_name,
                        "start_station_no": start_station_no,
                        "end_station_name": end_station_name,
                        "end_station_no": end_station_no,
                        "seat_no": seat_no,
                        "price": price,
                        "create_time": create_time,
                    }
                    create_order(order_info)
                    # 设置订单队列
                    print("进入订单队列")
                    create_order_queue(order_info)
                    # 设置死信队列
                    create_dead_queue(order_info)
                    time.sleep(2)
                    create_paid_queue(order_info)
                    request.close()
                    return result(200, {"message": "改签成功！",
                                        "data": {"train_no": train_no, "arrive_day": arrive_day,
                                                 "carriage_no": carriage_no, "passenger_name": passenger_name,
                                                 "order_id": order_id, "user_id": user_id, "price": price,
                                                 "seat_no": seat_no,
                                                 "start_station_no": start_station_no,
                                                 "end_station_name": end_station_name,
                                                 "end_station_no": end_station_no,
                                                 "start_station_name": start_station_name,
                                                 "create_time": create_time,
                                                 "passenger_card": passenger_card}})
                except Exception as e:
                    print(e)
                    return result(400, {"message": "由于网络异常，购票失败，请检查网络！"})
        else:
            return result(201, {"message": "购票失败，该车厢座位已售罄！"})
    except:
        return result(502, {"message": "数据有误"})


@app.route("/api/user/rebookSecond", methods=["POST"])
def user_rebook_second():
    try:
        data = json.loads(request.get_data())
        user_id = User.query.filter_by(username=data["username"]).first().id
        passenger_card = data["passenger_card"]
        train_no = data["train_no"]
        arrive_day = data["arrive_day"]
        start_station_name = data["start_station_name"]
        start_station_no = data["start_station_no"]
        end_station_name = data["end_station_name"]
        end_station_no = data["end_station_no"]
        carriage_no = data["carriage_no"]
        seat_no = data["seat_no"]
        price = data["price"]
        create_time = data["create_time"]
        passenger_name = Passenger.query.filter_by(card=passenger_card).first().name
        order_id = str(uuid.uuid4().hex)
        victim = Seat.query.filter_by(train_no=train_no, arrive_day=arrive_day, carriage_no=carriage_no).first()
        flag = plus_counter(train_no, carriage_no, arrive_day, victim.seat_count, user_id, passenger_card, order_id)
        print('flag:', flag)
        if flag:
            if flag == -1:
                return result(204, {"message": "已经为该乘客购买了本车次车票"})
            elif flag == -2:
                return result(205, {"message": "已经为该乘客抢到了车票，但是还未付款"})
            else:
                try:
                    # 把订单信息放入redis中，并设置过期时间
                    order_info = {
                        "order_id": order_id,
                        "user_id": user_id,
                        "passenger_card": passenger_card,
                        "train_no": train_no,
                        "carriage_no": carriage_no,
                        "arrive_day": arrive_day,
                        "start_station_name": start_station_name,
                        "start_station_no": start_station_no,
                        "end_station_name": end_station_name,
                        "end_station_no": end_station_no,
                        "seat_no": seat_no,
                        "price": price,
                        "create_time": create_time,
                    }
                    create_order(order_info)
                    # 设置订单队列
                    print("进入订单队列")
                    create_order_queue(order_info)
                    # 设置死信队列
                    create_dead_queue(order_info)
                    request.close()
                    return result(200, {"message": "改签订单抢购成功，请在15分钟内付款！",
                                        "data": {"train_no": train_no, "arrive_day": arrive_day,
                                                 "carriage_no": carriage_no, "passenger_name": passenger_name,
                                                 "order_id": order_id, "user_id": user_id, "price": price,
                                                 "seat_no": seat_no,
                                                 "start_station_no": start_station_no,
                                                 "end_station_name": end_station_name,
                                                 "end_station_no": end_station_no,
                                                 "start_station_name": start_station_name,
                                                 "create_time": create_time,
                                                 "passenger_card": passenger_card}})
                except Exception as e:
                    print(e)
                    return result(400, {"message": "由于网络异常，购票失败，请检查网络！"})
        else:
            return result(201, {"message": "购票失败，该车厢座位已售罄！"})
    except:
        return result(502, {"message": "数据有误"})


@app.route("/api/user/pay2", methods=["POST", "GET"])
def user_pay2():
    data = json.loads(request.get_data())
    order_info = data
    order_status = check_order(order_info)
    if order_status:
        if order_status == -1:
            return result(202, {"message": "订单已超时"})
        else:
            # 此处应该有一个支付函数逻辑，比如支付宝沙箱
            out_trade_no = order_info['order_id']
            price = order_info['charge']
            total_amount = price
            order_string = alipay.api_alipay_trade_page_pay(
                out_trade_no=out_trade_no,
                total_amount=total_amount,
                subject='火车票支付',
                return_url='http://localhost:9528/#/success',)
            url = "https://openapi-sandbox.dl.alipaydev.com/gateway.do?" + order_string
            return result(200, {"url": url})
    else:
        return result(203, {"message": "参数有误,数据不一致"})


@app.route("/api/user/refund", methods=["POST"])
def user_refund():
    try:
        order_info = json.loads(request.get_data())
        print(order_info)
        order_id = order_info['order_id']
        str_price = order_info['price']
        price = str_price[1:]
        refund_amount = int(price)
        # 此处应该有一个退款函数
        # 由于支付宝退款必须数目一致，所以先查，再改，再退款
        get_refund(order_info)
        Orders.query.filter_by(id=order_id).update({"status": "已退票"})
        db.session.commit()
        return result(200, {"message": "退票成功"})
    except Exception as e:
        print(e)
        return result(400, {"message": "退票失败"})


@app.route("/api/user/rebook", methods=["POST"])
def user_rebook():
    try:
        order_info = json.loads(request.get_data())
        order_id = order_info['order_id']
        if enter_rebook_queue(order_info):
            Orders.query.filter_by(id=order_id).update({"status": "已改签"})
            db.session.commit()
            return result(200, {"message": "改签成功！"})
    except Exception as e:
        print(e)
        return result(502, {"message": "数据有误"})


@app.route("/api/user/queryOrder", methods=["POST", "GET"])
def find_order():
    if request.method == "GET":
        temps = Orders.query.all()
        data = dict()
        data["data"] = []
        for temp in temps:
            dic = temp.__dict__
            del dic["_sa_instance_state"]
            dic['passenger_name'] = Passenger.query.filter_by(card=dic['passenger_card']).first().name
            print(Parking.query.filter_by(train_no=dic['train_no'], arrive_day=dic['arrive_day'],
                                          station_no=dic['start_station_no']).first(), "--------")
            dic['start_time'] = Parking.query.filter_by(train_no=dic['train_no'], arrive_day=dic['arrive_day'],
                                                        station_no=dic['start_station_no']).first().start_time
            dic['end_time'] = Parking.query.filter_by(train_no=dic['train_no'], arrive_day=dic['arrive_day'],
                                                      station_no=dic['end_station_no']).first().arrive_time
            dic['create_time'] = dic['create_time'].strftime("%Y-%m-%d %H:%M:%S")
            data["data"].append(dic)
        return result(200, data)
    else:
        try:
            data = json.loads(request.get_data())
            user_id = User.query.filter_by(username=data["username"]).first().id
            print("-------")
            try:
                passenger_card = data['passenger_card']
                print("-------")
                order_status = data['order_status']
                if passenger_card == '' and order_status == '':
                    temps = Orders.query.filter_by(user_id=user_id).all()
                elif passenger_card == '' and order_status != '':
                    temps = Orders.query.filter_by(user_id=user_id, status=order_status).all()
                elif passenger_card != '' and order_status == '':
                    temps = Orders.query.filter_by(user_id=user_id, passenger_card=passenger_card).all()
                elif passenger_card != '' and order_status != '':
                    temps = Orders.query.filter_by(user_id=user_id, passenger_card=passenger_card, status=order_status) \
                        .all()
            except Exception as e:
                print(e)
                temps = Orders.query.filter_by(user_id=user_id).all()
            data = dict()
            data["data"] = []
            for temp in temps:
                dic = temp.__dict__
                del dic["_sa_instance_state"]
                dic['passenger_name'] = Passenger.query.filter_by(card=dic['passenger_card']).first().name
                print(Parking.query.filter_by(train_no=dic['train_no'], arrive_day=dic['arrive_day'],
                                                station_no=dic['start_station_no']).first(), "--------")
                dic['start_time'] = Parking.query.filter_by(train_no=dic['train_no'], arrive_day=dic['arrive_day'],
                                                            station_no=dic['start_station_no']).first().start_time
                dic['end_time'] = Parking.query.filter_by(train_no=dic['train_no'], arrive_day=dic['arrive_day'],
                                                          station_no=dic['end_station_no']).first().arrive_time
                dic['create_time'] = dic['create_time'].strftime("%Y-%m-%d %H:%M:%S")
                data["data"].append(dic)
            print(data)
            return result(200, data)
        except Exception as e:
            print(e,"$$$$$$$$$$")
            return result(502, {"message": "数据有误,未传入用户名"})


@app.route("/api/user/queryOrderStatus", methods=["POST", "GET"])
def query_order_status():
    try:
        data = json.loads(request.get_data())
        order_id = data["order_id"]
        order_status = Orders.query.filter_by(id=order_id).first().status
        return result(200, {"status": order_status})
    except Exception as e:
        print(e)
        return result(502, {"message": "传入的参数有误！"})


@app.route("/api/user/deleteOrder", methods=["POST", "GET"])
def delete_order():
    try:
        data = json.loads(request.get_data())
        order_id = data['order_id']
        victim = Orders.query.filter_by(id=order_id).first()
        if victim:
            db.session.delete(victim)
            db.session.commit()
            return result(200)
        else:
            return result(201, {"message": '该订单不存在'})
    except Exception as e:
        print(e)
        return result(501, {"message": "数据有误"})


if __name__ == '__main__':
    app.run(debug=True)
